package com.kaifamiao.socket;

import java.io.*;
import java.net.*;
import java.util.HashSet;
import java.util.Set;

public class SecondServer {

    private static final Set<Socket> sockets = new HashSet<>();

    private static class ServiceThread extends Thread {

        private Socket socket;
        private String identifier;

        public ServiceThread(Socket socket) {
            this.socket = socket;
            this.prepare();
        }

        private void prepare() {
            // 获得远程主机地址 (因为是在服务器上获取，所以这里返回的是客户端的地址)
            InetSocketAddress sa = (InetSocketAddress)socket.getRemoteSocketAddress();
            String ip = sa.getAddress().getHostAddress();
            int port = sa.getPort();
            identifier = String.format("[%s:%d]", ip, port);
        }

        @Override
        public void run() {
            try {
                InputStream in = socket.getInputStream();
                Reader r = new InputStreamReader(in);
                BufferedReader br = new BufferedReader(r);
                String message;
                while ((message = br.readLine()) != null) {
                    String str = String.format("%s说: %s", identifier, message);
                    System.out.println( str );
                    for( Socket s : sockets ) {
                        PrintStream ps = new PrintStream(s.getOutputStream());
                        ps.println(str);
                    }
                }
            } catch ( IOException e ) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {

        final int port = 12345;
        final InetAddress address = InetAddress.getLocalHost();
        SocketAddress serverAddress = new InetSocketAddress( address, port);

        // 创建 ServerSocket 实例
        ServerSocket ss = new ServerSocket();
        // 绑定 IP地址 和 端口
        ss.bind( serverAddress );

        while(true) {
            System.out.println("正在监听客户端连接");
            Socket socket = ss.accept(); // 监听客户端连接
            // 将监听到的客户端对应的 Socket 添加到集合中
            sockets.add(socket);
            // 启动为客户端服务的线程
            new ServiceThread(socket).start();
            System.out.println("监听到: " + socket);
        }

    }

}
